package cn.bdqn.layui.service.productsuccess;

import cn.bdqn.layui.entity.Product;
import cn.bdqn.layui.entity.ProductSuccess;
import cn.bdqn.layui.mapper.ProductMapper;
import cn.bdqn.layui.mapper.ProductSuccessMapper;
import cn.bdqn.layui.service.rabbit.RabbitSenderService;
import cn.bdqn.layui.util.RandomUtil;
import cn.bdqn.layui.util.SnowFlake;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class ProductSuccessServiceImpl implements ProductSuccessService {


    @Resource
    ProductSuccessMapper productSuccessMapper;

    @Resource
    ProductMapper productMapper;

    @Resource
    RabbitSenderService rabbitSenderService;

    @Resource
    RedisTemplate redisTemplate;

    SnowFlake snowFlake = new SnowFlake(2, 3);

    /**
     * 商品秒杀核心业务逻辑的处理-redis的分布式锁
     * @param proId
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public boolean KillItem(Integer proId, Integer userId) {
        Boolean result = false;
        //todo:借助redis的原子操作实现分布式锁-对共享操作进行控制
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String key = new StringBuffer().append(proId).append(userId).append("redis").toString();
        String value = RandomUtil.generateOrderCode();
        Boolean falg = valueOperations.setIfAbsent(key, value);
        if (falg) {
            redisTemplate.expire(key, 30, TimeUnit.SECONDS);
            try {
                if (productSuccessMapper.countByProductUserId(proId, userId) <= 0) {
                    Product product = productMapper.findProduct(proId);
                    if (product != null) {
                        int i = productMapper.updateStackV1(proId);
                        if (i > 0) {
                            commonRecordProductSuccess(product, userId);
                            result = true;
                        }
                    }
                }
            } catch (Exception e) {
            } finally {
                if (value.equals(valueOperations.get(key).toString())) {
                    redisTemplate.delete(key);
                }
            }
        }
        return result;
    }

    /**
     * 商品秒杀核心业务逻辑的处理-redisson的分布式锁
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public void commonRecordProductSuccess(Product product, Integer userId) {
        ProductSuccess productSuccess = new ProductSuccess();
        //雪花算法
        String orderNo = String.valueOf(snowFlake.nextId());
        productSuccess.setCode(orderNo);
        productSuccess.setProId(product.getId());
        productSuccess.setUserId(userId);
        productSuccess.setStatus(0);
        productSuccess.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        int i = productSuccessMapper.insertSelective(productSuccess);
        if (i > 0) {
            //TODO:进行异步邮件消息的通知=rabbitmq+mail
            rabbitSenderService.sendProductSuccessEmailMsg(orderNo);

            //TODO:入死信队列，用于 “失效” 超过指定的TTL时间时仍然未支付的订单
            rabbitSenderService.sendKillSuccessOrderExpireMsg(orderNo);
        }
    }

}